import { Controller } from 'egg';
import { ModelStatus } from '../model/types'
import { uuid as uuidReg } from '../../utils/regular'

// 单挑数据缓存的KEY
const ONE_DATE_CATCH_KEY = 'ONE_DATE_CATCH_KEY'
// 列表数据缓存的KEY
const DATA_ARR_CATCH_KEY = 'DATA_ARR_CATCH_KEY'

export default class DataController extends Controller {

  /**
   * 更新单条数据
   */
  public async updateOne() {
    const { ctx } = this;
    ctx.w_validate_param_id()
    this.ctx.validate({
      data: {
        type: 'string',
        required: false
      },
      createTime: {
        type: 'w-date',
        required: false
      },
    });
    const [dataModel, menuModel] = await this.ctx.service.data.updateOne(this.ctx.params.id, this.ctx.w_body('data createTime'));
    // 清除缓存数据
    ctx.clearCache(`${ONE_DATE_CATCH_KEY}_${menuModel.uuid}`)
    this.ctx.sendSuccess(dataModel.createTime);
  }

  /**
   * 获取单条数据(要有权限)
   */
  public async getOne() {
    const { ctx } = this;
    ctx.w_validate_param_id()
    const data = await this.ctx.service.data.getOne(this.ctx.params.id);
    this.ctx.sendSuccess(data);
  }

  /**
   * 获取单条数据(不用权限)
   */
  public async getOneData() {
    const { ctx } = this;
    ctx.w_validate_param_uuid()
    const {uuid} = this.ctx.params
    const data = this.ctx.getCache(`${ONE_DATE_CATCH_KEY}_${uuid}`, async () => {
      return await this.ctx.service.data.getOneData(uuid);
    })
    this.ctx.sendSuccess(data);
  }

  /**
   * 获取单条数据(没办法做缓存)
   */
  public async getOneDatas() {
    const { ctx } = this;
    const { uuids } = ctx.query
    if (!uuids) {
      throw '参数必须带uuids'
    }
    const uuidArr = uuids.split(',')
    uuidArr.forEach(item => {
      if (!uuidReg.test(item)) {
        throw 'uuid 格式不正确'
      }
    });
    const arrayP = uuidArr.map((uuid) => {
      return this.ctx.service.data.getOneData(uuid)
    })
    const data = await Promise.all(arrayP);
    this.ctx.sendSuccess(data);
  }

  /**
   * 获取记录数据
   */
  public async record() {
    const { ctx } = this;
    ctx.w_validate_param_id()
    ctx.w_validate_page();
    this.ctx.validate({
      startTime: {
        type: 'w-date-num',
        required: false
      },
      endTime: {
        type: 'w-date-num',
        required: false
      },
    }, this.ctx.query);
    const data = await Promise.all([
      ctx.service.data.recordList(this.ctx.params.id, this.ctx.query),
      ctx.service.data.recordCount(this.ctx.params.id)
    ]);
    this.ctx.sendList(data);
  }

  /**
   * 删除单条数据
   */
  public async recordRemove() {
    const { ctx } = this;
    ctx.w_validate_param_id()
    await this.ctx.service.data.recordRemove(this.ctx.params.id);
    this.ctx.sendSuccess("ok");
  }

  /**
   * 恢复单条数据
   */
  public async restoreOne() {
    const { ctx } = this;
    ctx.w_validate_param_id()
    const {id} = this.ctx.params
    await this.ctx.service.data.restoreOne(this.ctx.params.id);
    // 清除缓存数据
    const uuid = await this.ctx.service.data.getUUIDWithId(id)
    ctx.clearCache(`${ONE_DATE_CATCH_KEY}_${uuid}`)
    this.ctx.sendSuccess("ok");
  }

  /**
   * 数组添加单条数据
   */
  public async arrayPush() {
    const { ctx } = this;
    ctx.w_validate_param_id()
    this.ctx.validate({
      data: {
        type: 'string',
      },
      index: {
        type: 'number',
        convertType: 'number',
        max: 1000,
        min: 0,
      },
    });
    const menuModel = await this.ctx.service.data.arrayPush(this.ctx.params.id, this.ctx.w_body('data index'));
    ctx.clearCache(`${DATA_ARR_CATCH_KEY}_${menuModel.uuid}`)
    this.ctx.sendSuccess("ok");
  }

  /**
   * 获取数据列表
   */
  public async arrayList() {
    const { ctx } = this;
    ctx.w_validate_param_id()
    ctx.w_validate_page();
    this.ctx.validate({
      status: {
        type: 'enum',
        values: [ `${ModelStatus.NORMAL}`, `${ModelStatus.DELETE}` ],
      },
      indexSort: {
        type: 'enum',
        values: [ '1', '-1' ],
      },
      startTime: {
        type: 'w-date-num',
        required: false
      },
      endTime: {
        type: 'w-date-num',
        required: false
      },
    }, this.ctx.query);
    const data = await Promise.all([
      this.ctx.service.data.arrayList(this.ctx.params.id, this.ctx.query),
      this.ctx.service.data.arrayListCount(this.ctx.params.id, this.ctx.query)
    ]);
    this.ctx.sendList(data);
  }

  /**
   * 获取数据列表(纯数据)
   */
  public async getArrayData() {
    const { ctx } = this;
    ctx.w_validate_param_uuid()
    const { uuid } = this.ctx.params
    const data = ctx.getListCache(`${DATA_ARR_CATCH_KEY}_${uuid}`, async () => {
      ctx.w_validate_page();
      this.ctx.validate({
        indexSort: {
          type: 'enum',
          values: [ '1', '-1' ],
          required: false,
          default: '1'
        },
        startTime: {
          type: 'w-date-num',
          required: false
        },
        endTime: {
          type: 'w-date-num',
          required: false
        },
      }, this.ctx.query);
      return await Promise.all([
        this.ctx.service.data.arrayListWithUUID(this.ctx.params.uuid, this.ctx.query),
        this.ctx.service.data.arrayListCountWithUUID(this.ctx.params.uuid, this.ctx.query)
      ]);
    })
    this.ctx.sendList(data);
  }

  /**
   * 修改数组中的数据
   */
  public async arrayListUpdate() {
    const { ctx } = this;
    ctx.w_validate_param_id()
    ctx.w_validate_page();
    this.ctx.validate({
      data: {
        type: 'string',
      },
      index: {
        type: 'number',
        convertType: 'number',
        max: 1000,
        min: 0,
      },
    });
    const model = await this.ctx.service.data.arrayListUpdate(this.ctx.params.id, this.ctx.w_body('data index'));
    const uuid = await this.ctx.service.data.getUUIDWithId(model.menuId)
    ctx.clearCache(`${DATA_ARR_CATCH_KEY}_${uuid}`)
    this.ctx.sendSuccess("ok");
  }

  /**
   * 删除数据到回收站
   */
  public async arrayListRecyclePush() {
    const { ctx } = this;
    ctx.w_validate_param_id()
    const { id } = this.ctx.params
    await this.ctx.service.data.arrayListRecycle(id);
    const uuid = await this.ctx.service.data.getUUIDWithDataId(id)
    ctx.clearCache(`${DATA_ARR_CATCH_KEY}_${uuid}`)
    this.ctx.sendSuccess("ok");
  }

  /**
   * 回收站撤销数据
   */
  public async arrayListRecyclePop() {
    const { ctx } = this;
    ctx.w_validate_param_id()
    const { id } = this.ctx.params
    await this.ctx.service.data.arrayListRecycle(id, false);
    const uuid = await this.ctx.service.data.getUUIDWithDataId(id)
    ctx.clearCache(`${DATA_ARR_CATCH_KEY}_${uuid}`)
    this.ctx.sendSuccess("ok");
  }

  /**
   * 删除数据还有他的记录数据
   */
  public async remove() {
    const { ctx } = this;
    ctx.w_validate_param_id()
    await this.ctx.service.data.remove(this.ctx.params.id);
    this.ctx.sendSuccess("ok");
  }
}
